-- Hier muss der Name eurer LOS Implementierung rein
require("classes")

Class{'Pet', name = String}

function Pet:create(n)
  self.name = n
end

function Pet:makeNoise(count)
  print(self.name..': '..self:getNoise())
end

function Pet:getNoise()
  return '???'
end

Class{'Dog', Pet}

function Dog:makeNoise(count)
  io.write(self.name..': ')
  while count > 1 do
    io.write(self:getNoise())
	count = count-1
  end
  print(self:getNoise())
end

function Dog:getNoise()
  return 'Woof!'
end

Class{'Cat', Pet}

function Cat:getNoise()
  return 'Meow'
end

Class{'Fish', Pet}

Class{'Parrot', Pet}

function Parrot:getNoise()
  return 'Crraa'
end

-- Aspects --

Aspect{'InnerLogger', adapts = {Pet}, before = {logBefore = '[^g]%w*'}, after = {logAfter = '[^g]%w*'}}
function InnerLogger:logBefore(methodName)
  print('>>>'..methodName..'>>>')
  return true
end
function InnerLogger:logAfter(methodName, result)
  print('<<<'..methodName..'<<<')
  return result
end

Aspect{'Louder', adapts = {Dog}, after = {loudNoise = 'getNoise'}}
function Louder:loudNoise(methodName, result)
  return string.upper(result)
end

Aspect{'Silent', adapts = {Dog}, before = {shutup = 'makeNoise'}}
function Silent:shutup(methodName, count)
  print('Shut up!')
  return false
end

Aspect{'Mimiced', adapts = {Dog, Cat}, after = {saveNoise = 'getNoise'}}
function Mimiced:saveNoise(methodName, result)
  savedNoise = result  -- global
  return result
end

Aspect{'Mimicry', adapts = {Parrot}, after = {loadNoise = 'getNoise'}}
function Mimicry:loadNoise(methodName, result)
  return savedNoise
end

Aspect{'OuterLogger', adapts = {Pet}, before = {logBefore = '[^g]%w*'}, after = {logAfter = '[^g]%w*'}}
function OuterLogger:logBefore(methodName)
  print('+++'..methodName..'+++')
  return true
end
function OuterLogger:logAfter(methodName, result)
  print('---'..methodName..'---')
  return result
end

-- Application --

InnerLogger:activate()
OuterLogger:activate()
Mimiced:activate()

d = Dog:create('Bello');
c = Cat:create('Schneeball')
f = Fish:create('Glubschi')
p = Parrot:create('Fuzzy');

d:makeNoise(3)
c:makeNoise(3)
f:makeNoise(3)
InnerLogger:deactivate()
OuterLogger:deactivate()

Louder:activate()
print('!LOUDER:')
d:makeNoise(2)
c:makeNoise(2)
f:makeNoise(2)

print('!SILENT:')
Silent:activate()
d:makeNoise(0)
c:makeNoise(0)
f:makeNoise(0)
Silent:deactivate()

print('!MIMICRY:')
p:makeNoise(2)
Mimicry:activate()
p:makeNoise(2)
d:makeNoise(2)
p:makeNoise(2)






